﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using ZhCun.DbCore;
using ZhCun.DbCore.BuildSQLText;
using ZhCun.DbCore.Cores;
using ZhCun.DbCore.Entitys;
using ZhCun.Utils;
using ZhCun.Utils.Helpers;

namespace ZhCun.CodeBuilder.BLL
{
    class DBHelper : DBContextDebug
    {
        static DBHelper()
        {
            DbType = EmDbType.SQLite;
            ConnStr = "Data Source=CodeBuilder.db;";
        }

        public readonly static EmDbType DbType;

        public readonly static string ConnStr;

        public DBHelper()
            : base(DbType, ConnStr)
        { }

        const string FN_LAST_TIME = "LastTime";

        protected override void ResultFinish(BaseResult result)
        {
            //TODO: 这里可以记录sql执行日志
            Console.WriteLine(result.SqlContent);
        }

        public ExecResult Insert<TEntity>(TEntity entity, bool autoId, bool autoUserId)
            where TEntity : EntityBase, new()
        {
            if (autoId)
            {
                var id = ReflectionHelper.GetPropertyValue<string>(entity, "Id");
                if (id.IsEmpty())
                {
                    id = GuidHelper.NewId();
                    ReflectionHelper.SetPropertyValue(entity, "Id", id);
                }
            }
            return base.Insert(entity);
        }

        public override ExecResult Insert<TEntity>(TEntity entity)
        {
            return Insert(entity, true, true);

            ////Id主键自动赋值
            //var id = ReflectionHelper.GetPropertyValue<string>(entity, "Id");
            //if (id.IsEmpty())
            //{
            //    id = GuidHelper.NewId();
            //    ReflectionHelper.SetPropertyValue(entity, "Id", id);
            //}
            //ReflectionHelper.SetPropertyValue(entity, FN_ADD_HOST, LoginHost);
            //ReflectionHelper.SetPropertyValue(entity, FN_ADD_USER_ID, CurrUserId);
            //return base.Insert(entity);
        }

        protected override ExecResult UpdateBase<TEntity>(TEntity entity, Func<ISqlBuilder, string> whereFun)
        {
            ReflectionHelper.SetPropertyValue(entity, FN_LAST_TIME, DateTime.Now);
            return base.UpdateBase(entity, whereFun);
        }

        protected override void BeforeExecSqlBuilder<TEntity>(ISqlBuilder sqlBuilder, EmDbOperation opType)
        {
        }
    }

    class BaseBLL
    {
        public BaseBLL()
        {
            DB = new DBHelper();
        }

        public DBHelper DB { get; }

        public string NewId()
        {
            return GuidHelper.NewId();
        }

        #region 返回结果的创建及定义

        /// <summary>
        /// 成功结果，可指定成功消息
        /// </summary>
        public ApiResult RetOK(string msg = null)
        {
            return ApiResult.RetOK(msg);
        }
        /// <summary>
        /// 成功结果，并返回实体对象的结果
        /// </summary>
        public ApiResult<T> RetOK<T>(T data, string msg = "")
        {
            return ApiResult.RetOK(data, msg);
        }

        /// <summary>
        /// 返回一个实体集合结果
        /// </summary>
        public ApiResultList<T> RetOK<T>(List<T> data, int count, string msg = "")
        {
            return ApiResult.RetOK(data, count, msg);
        }
        /// <summary>
        /// 返回空的 List 数据
        /// </summary>
        public ApiResultList<T> RetNullData<T>(string msg)
        {
            return new ApiResultList<T>() { code = ApiResult.CODE_VERIFY_FAIL, msg = msg };
        }
        /// <summary>
        /// 正常逻辑错误
        /// </summary>
        public ApiResult RetErr(string msg)
        {
            return ApiResult.RetErr(msg);
        }
        /// <summary>
        /// 返回数据对象的错误结果
        /// </summary>
        public ApiResult<T> RetErr<T>(string msg)
        {
            return ApiResult.RetErr<T>(msg);
        }
        ///// <summary>
        ///// 返回验证错误,data 表示属性名称
        ///// </summary>
        //public ApiResult<string> RetErr(string propertyName, string msg)
        //{
        //    return ApiResult.RetErr(propertyName, msg);
        //}
        /// <summary>
        /// 返回验证错误,data 表示属性名称
        /// </summary>
        public ApiResult<T> RetErr<T>(T t, string msg)
        {
            return new ApiResult<T>() { data = t, code = ApiResult.CODE_VERIFY_FAIL, msg = msg };
        }

        #endregion

        /// <summary>
        /// 获取高级搜索sqlBuiler
        /// </summary>
        public ISqlBuilder GetAdSearchSql(List<AdSearchDetail> searchList)
        {
            if (searchList == null || searchList.Count == 0)
            {
                return null;
            }
            ISqlBuilder sql = DB.CreateSqlBuilder("AD");
            foreach (var item in searchList)
            {
                //TODO: 防止sql注入 ConnectorSignStr 与 FieldName均为字符及下划线 组成
                if (item.ConnectorSignStr.Contains(" ") || item.FieldName.Contains(" "))
                {
                    sql.AddSQLParam(" 1!=1");
                    break;
                }

                sql.AddSQLText($" {item.ConnectorSignStr}");
                sql.AddSQLText($" {item.FieldName}");
                sql.AddSQLText($" {item.CompareSignStr}");
                var dataType = ConvertData.GetTypeByString(item.DataTypeStr);
                object val = Convert.ChangeType(item.SearchValue, dataType);
                sql.AddSQLParam(" {0}", val);
            }
            return sql;
        }


        public QueryCondition<TEntity> CreateQuery<TEntity>() where TEntity : EntityBase, new()
        {
            var query = DB.CreateQuery<TEntity>();
            return query;
        }
        /// <summary>
        /// 快捷创建一个包含表达式的QueryCondition
        /// </summary>
        public QueryCondition<TEntity> CreateQuery<TEntity>(Expression<Func<TEntity, bool>> whereExpress) where TEntity : EntityBase, new()
        {
            var query = DB.CreateQuery<TEntity>();
            query.WhereAnd(whereExpress);
            return query;
        }

        /// <summary>
        /// 查询分页结果（含高级搜索）
        /// </summary>
        public virtual QueryResult<TEntity> GetPagerResult<TEntity>(ArgPageData arg, out int total, Action<QueryCondition<TEntity>> QueryHandle)
            where TEntity : EntityBase, new()
        {
            var query = DB.CreateQuery<TEntity>();
            query.PageNo = arg.PageNo;
            query.PageSize = arg.PageSize;
            QueryHandle?.Invoke(query);
            var adSql = GetAdSearchSql(arg.AdSearchList);
            var ret = DB.Query<TEntity>(query, adSql);
            total = query.Total;
            return ret;
            //total = query.Total;            
        }
        /// <summary>
        /// 查询分页得到List，并返回指定条件的总记录数
        /// </summary>
        public virtual List<TEntity> GetPagerList<TEntity>(ArgPageData arg, out int total, Action<QueryCondition<TEntity>> QueryHandle)
            where TEntity : EntityBase, new()
        {
            var ret = GetPagerResult(arg, out total, QueryHandle);
            return ret.ToList();
        }

        public virtual List<TEntity> GetPagerList<TEntity>(int pageNo, int pageSize, out int total, Action<QueryCondition<TEntity>> QueryHandle)
            where TEntity : EntityBase, new()
        {
            return GetPagerList<TEntity>(new ArgPageData
            {
                PageNo = pageNo,
                PageSize = pageSize
            }, out total, QueryHandle);
        }

        public virtual ApiResultList<TEntity> GetPagerList<TEntity>(ArgPageData arg, Action<QueryCondition<TEntity>> QueryHandle)
            where TEntity : EntityBase, new()
        {
            var rList = GetPagerList(arg, out int total, QueryHandle);

            return RetOK(rList, total);
        }
    }
}